<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // call apply bind  => Function.prototype上  => 所有函数都能使用的拓展方法,改变函数调用时this的指向 

    // call(thisArg,arg1,arg2...argN)
    // 1. 调用原函数
    // 2. 在本次函数执行时,强制将this指向call方法的第一参数(对象), 如果不传参,或者传null / undefined => 不改变this的指向
    // 3. 如果原函数需要接收参数, 可以从第二参数开始,依次向后传递

    // apply(thisArg,[arg1,arg2...argN])
    // 1. 调用原函数
    // 2. 在本次函数执行时,强制将this指向call方法的第一参数(对象), 如果不传参,或者传null / undefined => 不改变this的指向
    // 3. 如果原函数需要接收参数, 

    // call  apply  => 都会先调用原函数,在本次函数执行过程中,将this强制指向方法的第一参数 
    //              => 属于借鸡生蛋 (只是将方法拿过来借用一次, 原方法不会收到影响)


    /* var obj = {
        a:1,
        b:2,
        fn:function(){
            console.log("obj.say执行了");
            console.log(this);
        }
    }*/

    // function fn(a,b){
    //     console.log("函数执行了", a, b);
    //     console.log(this);
    // }


    // fn();   // 普通调用

    //  1. 调用原函数
    // fn.call();

    //  2. 在本次函数执行时,强制将this指向call方法的第一参数(对象), 如果不传参,或者传null / undefined => 不改变this的指向
    // fn.call(null);
    // fn.call(document);
    // fn.call(Math);

    // 3. 如果原函数需要接收参数, 可以从第二参数开始,依次向后传递
    // fn.call(document,10,20);
    // fn.call(document.body,100,200);


    // apply 

    // function fn(a, b) {
    //     console.log("函数执行了", a, b);
    //     console.log(this);
    // }

    // fn.apply();

    // fn.apply(null);
    // fn.apply(document);
    // fn.apply(Math);

    // 如果原函数需要接收参数, 需要先将参数依次整合到数组中,再将数组作为第二参数传入 
    // fn.apply(document, [10, 20]);
    // fn.apply(document.body, [100, 200]);






</script>

</html>